#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
	
//密钥长度8字节,2组，每组4字节
#define NUM 8
#define LEN 4
#define WID 2


int KeyGenarator(int key1[NUM],int key2[NUM]);
//传入参数i为密钥序号，传出密钥数组key[NUM]

int S_DES(int key1[NUM],int key2[NUM],int m[NUM],int ctemp[NUM]);
//传入参数密钥数组key[NUM],传出密文字符数组

int main()
{
    int j,flag=1,test=0;
    int key1[NUM]= {0},key2[NUM]= {0};
    int c[NUM],m[NUM],ctemp[NUM];
int *ptr;

    printf("欢迎使用S-DES密钥穷举系统\n\n");
    printf("请输入密文:\n\n");
    for(j=0; j<NUM; j++)
        scanf("%d",&c[j]);


    printf("请输入明文:\n\n");
    for(j=0; j<NUM; j++)
        scanf("%d",&m[j]);

    do
    {
        KeyGenarator(key1,key2);
        S_DES(key1,key2,m,ctemp);
        for(j=0; j<NUM; j++)
        {
            if(ctemp[j]^c[j])
                continue;
            else if(j==7)
                flag=0;
        }

    }
    while(flag);

    printf("\n密钥key1：\n");
    for(j=0; j<NUM; j++)
        printf("%d ",key1[j]);
    printf("\n\n");

    printf("密钥key2：\n");
    for(j=0; j<NUM; j++)
        printf("%d ",key2[j]);
    printf("\n\n");

    return 0;
}

int KeyGenarator(int key1[NUM],int key2[NUM])
{

    int n;
    int i,j;

    srand(time(0));
    i = rand()%256;
    j = rand()%256;


    for(n=0; n<NUM; n++)
    {
        key1[n]=i%2;
        key2[n]=j%2;
        i/=2;
        j/=2;
        if(!i && !j)
        {
            break;
        }
    }

}

int S_DES(int key1[NUM],int key2[NUM],int m[NUM],int ctemp[NUM])
{

    int IP[NUM]= {2,6,3,1,4,8,5,7};
    int IPinv[NUM]= {4,1,3,5,7,2,8,6};
    int EP[NUM]= {4,1,2,3,2,3,4,1};
    int P4[NUM/2]= {2,4,3,1};

    int i,j;
    int c[NUM];
    int L[NUM/2],R[NUM/2],Rtemp[NUM/2],r1[NUM/2],r2[NUM/2],t[NUM/2];
    int s0[NUM*2]= {1,0,3,2,3,2,1,0,0,2,1,3,3,1,3,2};
    int s1[NUM*2]= {0,1,2,3,2,0,1,3,3,0,1,0,2,1,0,3};

//IP置换，分为L,R,R备份为temp
    for(i=0; i<NUM; i++)
    {
        if(i<NUM/2)
        {
            L[i] = m[IP[i]-1];
        }
        else
        {
            R[i-NUM/2] = m[IP[i]-1];
        }
    }
//OK

//第1轮festel
    for(i=0; i<NUM/2; i++)
    {
        Rtemp[i] = R[i];
    }

    for(i=0; i<NUM; i++)
    {
        if(i<NUM/2)
            r1[i] = R[EP[i]-1]^key1[i];
        else
            r2[i-NUM/2] = R[EP[i]-1]^key1[i];
    }

    t[0]=s0[(2*r1[0]+r1[3])*4+2*r1[1]+r1[2]]/2;
    t[1]=s0[(2*r1[0]+r1[3])*4+2*r1[1]+r1[2]]%2;
    t[2]=s1[(2*r2[0]+r2[3])*4+2*r2[1]+r2[2]]/2;
    t[3]=s1[(2*r2[0]+r2[3])*4+2*r2[1]+r2[2]]%2;

    for(i=0; i<NUM/2; i++)
    {
        R[i] = L[i]^t[P4[i]-1];
        L[i] = Rtemp[i];
    }
//OK

//第2轮festel
    for(i=0; i<NUM/2; i++)
    {
        Rtemp[i] = R[i];
    }

    for(i=0; i<NUM; i++)
    {
        if(i<NUM/2)
            r1[i] = R[EP[i]-1]^key2[i];
        else
            r2[i-NUM/2] = R[EP[i]-1]^key2[i];
    }

    t[0]=s0[(2*r1[0]+r1[3])*4+2*r1[1]+r1[2]]/2;
    t[1]=s0[(2*r1[0]+r1[3])*4+2*r1[1]+r1[2]]%2;
    t[2]=s1[(2*r2[0]+r2[3])*4+2*r2[1]+r2[2]]/2;
    t[3]=s1[(2*r2[0]+r2[3])*4+2*r2[1]+r2[2]]%2;

    for(i=0; i<NUM/2; i++)
    {
        R[i] = L[i]^t[P4[i]-1];
        L[i] = Rtemp[i];
    }
//OK
//最后1轮交叉
    for(i=0; i<NUM; i++)
    {
        if(i<NUM/2)
            c[i] = R[i];
        else
            c[i] = L[i-NUM/2];
    }
//逆IP置换
    for(i=0; i<NUM; i++)
    {
        ctemp[i]=c[IPinv[i]-1];
    }
    return 0;
}

